package com.yihu.wlyy.service.app.account;

import java.util.*;

import com.yihu.wlyy.entity.*;
import com.yihu.wlyy.entity.address.City;
import com.yihu.wlyy.entity.address.Province;
import com.yihu.wlyy.entity.address.Town;
import com.yihu.wlyy.entity.consult.Consult;
import com.yihu.wlyy.entity.consult.ConsultTeamDoctor;
import com.yihu.wlyy.entity.doctor.Doctor;
import com.yihu.wlyy.entity.doctor.DoctorPatientGroup;
import com.yihu.wlyy.entity.doctor.DoctorPatientGroupInfo;
import com.yihu.wlyy.entity.doctor.DoctorTeam;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.repository.*;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.util.EncodesUtil;

/**
 * 医生基本信息类.
 *
 * @author George
 */
// Spring Service Bean的标识.
@Component
@Transactional
public class DoctorInfoService extends BaseService {

    @Autowired
    private DoctorDao doctorDao;
    @Autowired
    private ProvinceDao provinceDao;
    @Autowired
    private CityDao cityDao;
    @Autowired
    private TownDao townDao;
    @Autowired
    private DoctorTeamDao doctorTeamDao;
    @Autowired
    private DrHealthTeamMemberDao doctorTeamDoctor;
    @Autowired
    private DoctorPatientGroupInfoDao doctorPatientGroupInfoDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private ConsultTeamDoctorDao consultTeamDoctorDao;
    @Autowired
    private WlyyPatientSickDao wlyyPatientSickDao;
    @Autowired
    private PatientDao patientDao;
    @Autowired
    private ConsultDao consultDao;
    @Autowired
    private SignFamilyDao signFamilyDao;

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    public List<Object> getDoctorSignPatients(String doctor){
        return signFamilyDao.findDoctorSignPatients(doctor);
    }

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    public List<Object> getDoctorSignPatientsLikeName(String doctor,String patientName){
        return signFamilyDao.findDoctorSignPatientsLikeName(doctor,patientName);
    }

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    public List<Object> getDoctorSignPatientsBySignType(String doctor,int type){
        return signFamilyDao.findDoctorSignPatientsBySignType(doctor,type);
    }

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    public List<Object> getDoctorSignPatientsByTypeName(String doctor,int type,String patientName){
        return signFamilyDao.findDoctorSignPatientsByTypeName(doctor,type,patientName);
    }

    public Doctor findDoctorByCode(String code) {
        return doctorDao.findByCode(code);
    }

    public Doctor findDoctorByMobile(String mobile) {
        return doctorDao.findByMobile(mobile);
    }

    /**
     * 获取正常医生
     *
     * @param mobile
     * @return
     */
    public Doctor findNormalByMobile(String mobile) {
        return doctorDao.findNormalByMobile(mobile);
    }

    /**
     * 更新医生基本信息
     *
     * @param doctor
     * @return
     */
    public Doctor updateDoctor(Doctor doctor) {
        Province province = provinceDao.findByCode(doctor.getProvince());
        if (province != null) {
            doctor.setProvinceName(province.getName());
        }
        City city = cityDao.findByCode(doctor.getCity());
        if (city != null) {
            doctor.setCityName(city.getName());
        }
        Town town = townDao.findByCode(doctor.getTown());
        if (town != null) {
            doctor.setTownName(town.getName());
        }
        // Hospital hospital = hospitalDao.findByCode(doctor.getHospital());
        // if(hospital != null){
        // doctor.setHosptialName(hospital.getName());
        // }
        // HospitalDept dept = hospitalDeptDao.findByCode(doctor.getDept());
        // if(dept != null){
        // doctor.setDeptName(dept.getName());
        // }
        // Job job = jobDao.findByCode(doctor.getJob());
        // if(job != null){
        // doctor.setJobName(job.getName());
        // }
        return doctorDao.save(doctor);
    }

    /**
     * 修改医生密码
     */
    public void updateDoctorPwd(Doctor doctor) {
        EncodesUtil.entryptPassword(doctor);
        doctorDao.save(doctor);
    }

    /**
     * 查询指定医生下的患者
     *
     * @param doctor
     * @return
     */
    public List<Object> findPatientByDoctorSign(String doctor) {
        return doctorDao.findPatientByDoctorSign(doctor);
    }

    public Page<Object> findPatientByDoctorSign(String doctor, long id,
                                                int pagesize, String patientName){
        // return doctorDao.findPatientByDoctorSign(doctor);

        Page<Object> signList = null;

        if (pagesize <= 0) {
            pagesize = 10;
        }
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pagesize);

        if (StringUtils.isEmpty(patientName)) {
            // doctorDao.findPatientByDoctorSign(doctor);
            if (id > 0) {
                signList = doctorDao.findPatientByDoctorSign(doctor, id,
                        pageRequest);

            } else {
                signList = doctorDao.findPatientByDoctorSign(doctor,
                        pageRequest);
            }
        } else {
            patientName = "%" + patientName + "%";
            if (id > 0) {
                signList = doctorDao.findPatientByDoctorSign(doctor, id,
                        patientName, pageRequest);

            } else {
                signList = doctorDao.findPatientByDoctorSign(doctor,
                        patientName, pageRequest);
            }
        }

        return signList;
    }

    /**
     * 查该医生管理的患者总数
     *
     * @param doctor
     * @return
     */
    public int amountPatientByDoctorSign(String doctor) {
        return doctorDao.amountPatientByDoctorSign(doctor);
    }

    /**
     * 查询指定医生的患者分组
     *
     * @param doctor
     * @return
     */
    public Iterable<DoctorPatientGroup> findDoctorPatientGroup(String doctor) {
        return doctorDao.findDoctorPatientGroup(doctor);
    }

    public Patient findPatientByCode(String code) {
        return doctorDao.findPatientByCode(code);
    }

    public DoctorPatientGroupInfo findGroup(String user, String doctor) {
        return doctorDao.findGroup(user, doctor);
    }

    /**
     * 根据医院信息获取医生列表
     *
     * @param query    查询条件 ：医生名称
     * @param id
     * @param hospital 医院标识
     *                 页数
     * @return
     */
    public Page<Doctor> getDoctorListByHospital(String query, String hospital,
                                                long id, int pageSize) {
        // 排序
        Sort sort = new Sort(Direction.DESC, "id");
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pageSize, sort);
        // 查询全部
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (StringUtils.isNotEmpty(query)) {
            filters.put("name", new SearchFilter("name", Operator.LIKE, query));
        }
        if(StringUtils.isNotEmpty(hospital)){
            hospital=hospital.substring(0,8);
            filters.put("hospital", new SearchFilter("hospital", Operator.LIKE,
                    hospital));
        }
        if (id > 0) {
            filters.put("id", new SearchFilter("id", Operator.LT, id));
        }
        filters.put("level", new SearchFilter("level", Operator.EQ, 2));
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(
                filters.values(), Doctor.class);
        return doctorDao.findAll(spec, pageRequest);
    }

    public List<Doctor> getDoctorCombobxByHospital(String type, String hospital) {

        return doctorDao.getDoctorCombobxByHospital(hospital, Integer.valueOf(type));
    }

    public Doctor getDoctor(int consultType, String patientCode) {
        //根据病人ID查找团队
        //DoctorTeam doctorTeam =doctorTeamDao.getBy
        return null;
    }

    public Page<Doctor> getDoctorListByPatientCode(int consultType, String patientCode, String name, int page, int pageSize) {
        //
        return null;
    }

    public Page<Doctor> getDoctorListByHospital(String name, String paitentCode, Integer page, Integer pageSize) {
        if (pageSize == null | pageSize <= 0) {
            pageSize = 10;
        }
        if (page == null | page <= 0) {
            page = 1;
        }
        // 排序
        Sort sort = new Sort(Sort.Direction.DESC, "name");
        // 分页信息
        PageRequest pageRequest = new PageRequest(page - 1, pageSize, sort);
        // 查询全部
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (StringUtils.isNotEmpty(name)) {
            filters.put("name", new SearchFilter("name", SearchFilter.Operator.LIKE, name));
        }
        filters.put("status", new SearchFilter("status", SearchFilter.Operator.EQ, 1));
        filters.put("level", new SearchFilter("level", SearchFilter.Operator.EQ, 1));
        filters.put("iscertified", new SearchFilter("iscertified", SearchFilter.Operator.EQ, 1));
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(filters.values(), Doctor.class);

        return doctorDao.findAll(spec, pageRequest);
    }

    public void doctor_1_Toteam(String teamCode, String doctor, String doctorName, String groupCode, String loginCode, String parientCode, String sickName, String sickNCode) {
        //得到患者所在的团队
        DoctorTeam doctorTeam = doctorTeamDao.findByParientCode(parientCode);

        //添加专科医生
        //判断专科医生之前是否已经加入到这个团队
        DrHealthTeamMember wlyyDoctorTeamDoctorTemp = doctorTeamDoctor.findMemberCodeAndTeam(doctorTeam.getCode(), doctor);
        if (wlyyDoctorTeamDoctorTemp != null) {

        } else {
            Patient patient = patientDao.findByCode(parientCode);
            patient.setDisease(Integer.valueOf(sickNCode));

            //更新之前这个团队的专业医生的del为0
            doctorTeamDoctor.updateType1Del(doctorTeam.getCode());
            //更新之前的患者病种表的del为0
            wlyyPatientSickDao.updateType1Del(parientCode, sickNCode);
            // 专科医生没有分组的概念
            DrHealthTeamMember wlyyDoctorTeamDoctor = new DrHealthTeamMember();
            wlyyDoctorTeamDoctor.setTeam(doctorTeam.getCode());
            wlyyDoctorTeamDoctor.setMemberCode(doctor);
            wlyyDoctorTeamDoctor.setName(doctorName);
            wlyyDoctorTeamDoctor.setDel("1");
            wlyyDoctorTeamDoctor.setType(1);
            wlyyDoctorTeamDoctor.setSignType("2");//家庭签约
            wlyyDoctorTeamDoctor.setCode(getCode());
            wlyyDoctorTeamDoctor.setCzrq(new Date());
            doctorTeamDoctor.save(wlyyDoctorTeamDoctor);

            //添加患者患病表
            WlyyPatientSick wlyyPatientSick = new WlyyPatientSick();
            wlyyPatientSick.setDel("1");//未删除
            wlyyPatientSick.setCzrq(new Date());
            wlyyPatientSick.setCode(getCode());
            wlyyPatientSick.setPatientCode(parientCode);
            wlyyPatientSick.setDoctorCode(doctor);
            wlyyPatientSick.setSickName(sickName);
            wlyyPatientSick.setSickCode(sickNCode);
            wlyyPatientSick.setSignType("2");//家庭签约
            wlyyPatientSickDao.save(wlyyPatientSick);
        }
        //把患者所在的健康管理师的组转慢病
        //查找出团队的全科医生
        //DrHealthTeamMember doctor2= doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(),"2");
        //查找出团队的健康管理师
        //DrHealthTeamMember doctor3= doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(),"3");
        //把患者转到的慢病组里
        doctorPatientGroupInfoDao.updateGroupByParient(parientCode);

    }

    public Doctor getDoctor2ByParient(String parientCode, String consultCode) {
        //得到咨询的类别
        Consult consult = consultDao.findByCode(consultCode);
//		//查找病人所在的团队
        DoctorTeam doctorTeam = doctorTeamDao.findByParientCodeAndSignType(parientCode, "" + consult.getType());
        //得到团队的全科医生
        DrHealthTeamMember drHealthTeamMember = doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(), 2);
        //得到全科医生
        Doctor doctor = doctorDao.findByCode(drHealthTeamMember.getMemberCode());
        //判断全科医生是否已经加入讨论组
        ConsultTeamDoctor consultTeamDoctor = consultTeamDoctorDao.getByConsultCodeAndDoctorCode(consultCode, doctor.getCode());
        if (consultTeamDoctor != null) {
            return null;
        }
        return doctor;
    }

    public List<Map> findNoInConsultDoctor(String existDoc, String consultCode, int page, int pageSzie) {
        int start = (page - 1) * pageSzie;
        String sql = "select p.* from wlyy_doctor p where " +
                "NOT EXISTS (SELECT 1 from wlyy_consult_team_doctor d WHERE d.to_doctor=p.code and d.consult='" + consultCode + "') " +
                " and p.level = 1 and p.iscertified=1 and p.status=1 and p.code<>'" + existDoc + "'" +
                " ORDER BY p.code limit " + start + "," + pageSzie;
        List rs = jdbcTemplate.queryForList(sql);
        return rs;
    }

    public int countNoInConsultDoctor(String existDoc, String consultCode) {
        String sql = "SELECT count(*) as c FROM (" +
                "select 1 as c from wlyy_doctor p where " +
                "NOT EXISTS (SELECT 1 from wlyy_consult_team_doctor d WHERE d.to_doctor=p.code and d.consult='" + consultCode + "') " +
                " and p.level = 1 and p.iscertified=1 and p.status=1 and p.code<>'" + existDoc + "'" +
                ") b";
        List rs = jdbcTemplate.queryForList(sql);
        return ((Long) ((Map) rs.get(0)).get("c")).intValue();
    }

    public Map<String, Object> getDoctor1ByParient(String consultCode, String parientCode, Integer page, Integer pageSzie) {
        Map<String, Object> returnMap = new HashMap<>();
        if (pageSzie == null | pageSzie <= 0) {
            pageSzie = 10;
        }
        if (page == null | page <= 0) {
            page = 1;
        }
        Consult consult = consultDao.findByCode(consultCode);
        if (consult.getType() == 2) {
            //查找病人所在的团队
            DoctorTeam doctorTeam = doctorTeamDao.findByParientCodeAndSignType(parientCode, consult.getType() + "");
            //得到团队的专科医生

            DrHealthTeamMember drHealthTeamMember = doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(), 1);
            String existDoc = drHealthTeamMember != null ? drHealthTeamMember.getMemberCode() : null;
            List<Map> rs = findNoInConsultDoctor(existDoc, consultCode, page, pageSzie);
            Doctor doctor = null;

            List<JSONObject> newDoctors = new ArrayList<>();
            JSONObject json;
            if (page == 1 && drHealthTeamMember != null) {
                //如果专科存在
                if (consultTeamDoctorDao.isExist(consultCode, drHealthTeamMember.getMemberCode()) == 0) {
                    doctor = doctorDao.findByCode(drHealthTeamMember.getMemberCode());//专科医生
                    if (doctor != null) {
                        json = new JSONObject();
                        json.put("code", doctor.getCode());
                        json.put("name", doctor.getName());
                        json.put("photo", doctor.getPhoto());
                        json.put("id", doctor.getId());
                        json.put("hospital", doctor.getHospital());
                        json.put("hosptialName", doctor.getHosptialName());
                        newDoctors.add(json);
                    }
                }
            }

            if (rs != null) {
                for (Map m : rs) {
                    json = new JSONObject();
                    json.put("code", m.get("code"));
                    json.put("name", m.get("name"));
                    json.put("photo", m.get("photo"));
                    json.put("id", m.get("id"));
                    json.put("hospital", m.get("hospital"));
                    json.put("hosptialName", m.get("hospital_name"));
                    newDoctors.add(json);
                }
            }

            returnMap.put("doctors", newDoctors);
            int total = countNoInConsultDoctor(existDoc, consultCode);
            returnMap.put("totalPage", total / pageSzie + (total % pageSzie > 0 ? 1 : 0));
        } else {
            //三师只可以邀请自己的专科医生
            //查找病人所在的团队
            DoctorTeam doctorTeam = doctorTeamDao.findByParientCodeAndSignType(parientCode, consult.getType() + "");
            DrHealthTeamMember drHealthTeamMember = doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(), 1);
            Doctor doctor = doctorDao.findByCode(drHealthTeamMember.getMemberCode());
            List<JSONObject> newDoctors = new ArrayList<>();

            JSONObject json = new JSONObject();
            json.put("code", doctor.getCode());
            json.put("name", doctor.getName());
            json.put("photo", doctor.getPhoto());
            json.put("id", doctor.getId());
            json.put("hospital", doctor.getHospital());
            json.put("hosptialName", doctor.getHosptialName());
            newDoctors.add(json);

            returnMap.put("doctors", newDoctors);
            returnMap.put("totalPage", 1);
        }
        return returnMap;
    }

    public List<Doctor> findDoctorByLevelAndHospital(String hospital, Integer level) {
        return doctorDao.findDoctorByLevelAndHospital(hospital,level);
    }

    /**
     * 更新医生身份证号
     *
     * @param idcard
     * @param doctor
     * @return
     */
    public boolean updateDoctorIdcard(String idcard,String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if(doc == null){
            throw new Exception("医生不存在");
        }
        doc.setIdcard(idcard);
        return true;
    }

    /**
     * 更新医生专长
     *
     * @param expertise
     * @param doctor
     * @return
     */
    public boolean updateExpertise(String expertise,String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if(doc == null){
            throw new Exception("医生不存在");
        }
        doc.setExpertise(expertise);
        return true;
    }

    /**
     * 更新医生性别
     *
     * @param sex
     * @param doctor
     * @return
     */
    public boolean updateSex(int sex,String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if(doc == null){
            throw new Exception("医生不存在");
        }
        doc.setSex(sex);
        return true;
    }

    /**
     * 更新医生介绍
     *
     * @param introduce
     * @param doctor
     * @return
     */
    public boolean updateIntroduce(String introduce,String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if(doc == null){
            throw new Exception("医生不存在");
        }
        doc.setIntroduce(introduce);
        return true;
    }

    /**
     * 设置医生为名医
     * @param doctorCode
     */
    @Transactional
    public void setFamous(String doctorCode,Integer status) {
        Doctor doctor=doctorDao.findByCode(doctorCode);
        //如果是空或者大于1 默认是关闭名医
        if(status==null||status>1){
            status=0;
        }
        doctor.setIsFamous(status);
    }
}
